#pragma once
#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h> // For socket functions
#include <netinet/in.h> // For sockaddr_in
#include <arpa/inet.h> // For inet_ntoa
#include <unistd.h> // For close
#include <sys/epoll.h>
#include <unordered_map>
#include <sstream> 
#include "../cmd/cmd.h"
#include "../cmd/cmdfactor.h"
#include "../sql/sql.h"
#include "../threadpoll/threadpool.h"


using std::istringstream;
using std::string;
using std::cout;
using std::endl;
using std::unordered_map;


const int EPOLL_SIZE=100;
const int MAX_EVENTS=100;
const int BUFFER_SIZE=1024;

class Socket
{
public:
    Socket() : ip(""), port(0) {};
    Socket(const std::string& ip, int port) : ip(ip), port(port) {} ;
    virtual ~Socket(){};

protected:
    string ip;
    int port;

    char buffer[1024];

};

class cSocket : public Socket
{
public:
    cSocket(){};
    cSocket(string ip, int port) : Socket(ip, port) {} ;
    ~cSocket(){};

    int clientsocketid;


    bool init();
    bool sendmsg(string msg);
    bool deinit(){};
    string recvmsg();
};


class sSocket : public Socket 
{
public:
    sSocket(){};
    sSocket(string ip, int port) : Socket(ip, port) {} ;
    ~sSocket(){};

    int serversocketid;
    unordered_map<int,string> clientsocketidname;


    bool init();
    bool epolldeal();
    bool sendmsg(string msg, int clientsocketid);
    bool deinit(){};
    string recvmsg();

    cmd* cmdptr;
    threadpool * threadpoolptr;

private:
    void handleclient(int client_socket);

};
